package com.atguigu;

import java.util.Map;

import javax.sql.DataSource;

import org.junit.Test;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;

import com.atguigu.aop.MathCalculator;
import com.atguigu.bean.Blue;
import com.atguigu.bean.Boss;
import com.atguigu.bean.Car;
import com.atguigu.bean.Color;
import com.atguigu.bean.Person;
import com.atguigu.bean.Yellow;
import com.atguigu.config.MainConfig;
import com.atguigu.config.MainConfig2;
import com.atguigu.config.MainConfigOfAOP;
import com.atguigu.config.MainConfigOfLifeCycle;
import com.atguigu.config.MainConfigOfProfile;
import com.atguigu.config.MainConfigOfPropertyValues;
import com.atguigu.config.MainConifgOfAutowired;
import com.atguigu.dao.BookDao;
import com.atguigu.ext.ExtConfig;
import com.atguigu.service.BookService;
import com.atguigu.tx.TxConfig;
import com.atguigu.tx.UserServiceTx;

public class Main {

	public static void main(String[] args) {
		SpringApplication.run(App.class, args);
	}
	
	@Test
	public void test01(){
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAOP.class);
		//1、不要自己创建对象
//		MathCalculator mathCalculator = new MathCalculator();
//		mathCalculator.div(1, 1);
		MathCalculator mathCalculator = applicationContext.getBean(MathCalculator.class);
		mathCalculator.div(1, 0);
		applicationContext.close();
	}
	
	@Test
	public void test02(){
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConifgOfAutowired.class);
		
		BookService bookService = applicationContext.getBean(BookService.class);
		System.out.println(bookService);
		
		BookDao bean = applicationContext.getBean(BookDao.class);
		System.out.println(bean);
		
		Boss boss = applicationContext.getBean(Boss.class);
		System.out.println(boss);//boss中的car是从容器中获取的
		
		Car car = applicationContext.getBean(Car.class);
		System.out.println(car);
		
		Color color = applicationContext.getBean(Color.class);
		System.out.println(color);
		
		System.out.println(applicationContext);
		
		applicationContext.close();
	}
	
	@Test
	public void test03(){
		AnnotationConfigApplicationContext applicationContext  = new AnnotationConfigApplicationContext(ExtConfig.class);
		
		//发布事件；
		applicationContext.publishEvent(new ApplicationEvent(new String("我发布的时间")) {});
		
		applicationContext.close();
	}
	
	@Test
	public void test04(){
		//1、创建ioc容器
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfLifeCycle.class);
		System.out.println("容器创建完成...");
		
		applicationContext.getBean("car");
		
		//关闭容器,单实例：容器关闭的时候，多实例：容器不会管理这个bean；容器不会调用销毁方法；
		applicationContext.close();
	}
	
	
	//1、使用命令行动态参数: 在虚拟机参数位置加载 -Dspring.profiles.active=test
		//2、代码的方式激活某种环境；
		@Test
		public void test05(){
			AnnotationConfigApplicationContext applicationContext = 
					new AnnotationConfigApplicationContext();
			//1、创建一个applicationContext
			//2、设置需要激活的环境
			applicationContext.getEnvironment().setActiveProfiles("dev");
//			applicationContext.getEnvironment().setActiveProfiles("dev","test");
			
			//3、注册主配置类
			applicationContext.register(MainConfigOfProfile.class);
			//4、启动刷新容器
			applicationContext.refresh();
			
			//根据类的类型，获取容器中的bean对象
			String[] namesForType = applicationContext.getBeanNamesForType(DataSource.class);
			for (String string : namesForType) {
				System.out.println(string);
			}
			
			Yellow bean = applicationContext.getBean(Yellow.class);
			System.out.println(bean);
			applicationContext.close();
		}
		
		@Test
		public void test06(){
			AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfPropertyValues.class);
			printBeans(applicationContext);
			System.out.println("=============");
			
			Person person = (Person) applicationContext.getBean("person");
			System.out.println(person);
			
			ConfigurableEnvironment environment = applicationContext.getEnvironment();
			String property = environment.getProperty("person.nickName");//获取配置文件中的值
			System.out.println(property);
			applicationContext.close();
		}
		
		private void printBeans(AnnotationConfigApplicationContext applicationContext){
			String[] definitionNames = applicationContext.getBeanDefinitionNames();
			for (String name : definitionNames) {
				System.out.println(name);
			}
		}
		
		@Test
		public void test07(){
			AnnotationConfigApplicationContext applicationContext = 
				 	new AnnotationConfigApplicationContext(TxConfig.class);
		
			UserServiceTx userService = applicationContext.getBean(UserServiceTx.class);
			
			userService.insertUser();
			applicationContext.close();
		}
		
		@Test
		public void test08(){
			AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
			
			printBeans1(applicationContext);
			Blue bean = applicationContext.getBean(Blue.class);
			System.out.println(bean);
			
			//工厂Bean获取的是调用getObject创建的对象
			Object bean2 = applicationContext.getBean("colorFactoryBean");
			Object bean3 = applicationContext.getBean("colorFactoryBean");
			System.out.println("bean的类型："+bean2.getClass());
			System.out.println(bean2 == bean3);
			
			Object bean4 = applicationContext.getBean("&colorFactoryBean");
			System.out.println(bean4.getClass());
		}
		
		private void printBeans1(AnnotationConfigApplicationContext applicationContext){
			String[] definitionNames = applicationContext.getBeanDefinitionNames();
			for (String name : definitionNames) {
				System.out.println(name);
			}
		}
		
		@Test
		public void test09(){
			AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);

			String[] namesForType = applicationContext.getBeanNamesForType(Person.class);
			ConfigurableEnvironment environment = applicationContext.getEnvironment();
			//动态获取环境变量的值；Windows 10
			String property = environment.getProperty("os.name");
			System.out.println(property);
			for (String name : namesForType) {
				System.out.println(name);
			}
			
			Map<String, Person> persons = applicationContext.getBeansOfType(Person.class);
			System.out.println(persons);
			
		}
		
		@Test
		public void test10(){
			AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
			
			String[] definitionNames = applicationContext.getBeanDefinitionNames();
			for (String name : definitionNames) {
				System.out.println(name);
			}

			System.out.println("ioc容器创建完成....");
			Object bean = applicationContext.getBean("person");
			Object bean2 = applicationContext.getBean("person");
			System.out.println(bean == bean2);//是相等的，默认是单例的。
		}
		
		@SuppressWarnings("resource")
		@Test
		public void test11(){
			AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
			String[] definitionNames = applicationContext.getBeanDefinitionNames();
			for (String name : definitionNames) {//IOC容器中的所有的对象的名字
				System.out.println(name);
			}
		}
}
